package com.imis.base.util.table.model;

import com.imis.base.constant.DataBaseConstant;
import com.imis.base.util.ConvertUtils;
import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 * ColumnMeta<br>
 * 数据库表处理对象
 * </p>
 *
 * @author XinLau
 * @version 1.0
 * @since 2020年09月28日 17:36
 */
@Setter
@Getter
public class ColumnMeta {
    /**
     * 数据表名
     */
    private String tableName;
    /**
     * 数据库表列编号
     */
    private String columnId;
    /**
     * 数据库表列名字
     */
    private String columnName;
    /**
     * 数据库表列长度
     */
    private int columnSize;
    /**
     * 数据库表列类型
     */
    private String columnType;
    /**
     * 数据库表列备注
     */
    private String columnComment;
    /**
     * 默认值
     */
    private String columnDefaultValue;
    /**
     * 小数位数
     */
    private int decimalDigits;
    /**
     * Y 是 N 否
     */
    private String isNullable;
    /**
     * 主键策略
     */
    private String primaryKeyType;
    /**
     * 原来的字段名
     */
    private String oldColumnName;

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof ColumnMeta)) {
            return false;
        }
        ColumnMeta meta = (ColumnMeta) obj;
        //时间类型不比较长度
        if (columnType.contains(DataBaseConstant.DATE_) || columnType.contains(DataBaseConstant.BLOB_) || columnType.contains(DataBaseConstant.TEXT_)) {
            return columnName.equals(meta.getColumnName())
                    && isNullable.equals(meta.isNullable)
                    && isEquals(columnComment, meta.getColumnComment()) && isEquals(columnDefaultValue, meta.getColumnDefaultValue());
        }
          /*else if (columnType.contains(DataBaseConstant.INT)) {
             return columnName.equals(meta.getColumnName())&& columnType.equals(meta.getColumnType())
            &&isNullable.equals(meta.isNullable);
        } */

        else {
            return columnType.equals(meta.getColumnType())
                    && isNullable.equals(meta.isNullable) && columnSize == meta.getColumnSize()
                    && isEquals(columnComment, meta.getColumnComment()) && isEquals(columnDefaultValue, meta.getColumnDefaultValue());
        }
    }

    /**
     * 新增对比方法： 针对Sqlserver2008数据库，不对比字段备注和默认值
     *
     * @param obj      - 对象
     * @param dataType - 数据库类型
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/9/30 10:14
     */
    public Boolean equalsByDataType(Object obj, String dataType) {
        if (obj == this) {
            return Boolean.TRUE;
        }
        if (!(obj instanceof ColumnMeta)) {
            return Boolean.FALSE;
        }
        ColumnMeta meta = (ColumnMeta) obj;
        if (DataBaseConstant.DB_TYPE_SQL_SERVER.equals(dataType)) {
            // 时间类型不比较长度
            if (columnType.contains(DataBaseConstant.DATE_) || columnType.contains(DataBaseConstant.BLOB_) || columnType.contains(DataBaseConstant.TEXT_)) {
                return columnName.equals(meta.getColumnName()) && isNullable.equals(meta.isNullable);
            } else {
                return columnType.equals(meta.getColumnType()) && isNullable.equals(meta.isNullable) && columnSize == meta.getColumnSize();
            }
        } else if (DataBaseConstant.DB_TYPE_POSTGRE_SQL.equals(dataType)) {
            // Text类型不比较长度
            if (columnType.contains(DataBaseConstant.DATE_) || columnType.contains(DataBaseConstant.BLOB_) || columnType.contains(DataBaseConstant.TEXT_)) {
                return columnName.equals(meta.getColumnName()) && isNullable.equals(meta.isNullable);
            } else {
                return columnType.equals(meta.getColumnType()) && isNullable.equals(meta.isNullable) && columnSize == meta.getColumnSize();
            }
        } else if (DataBaseConstant.DB_TYPE_ORACLE.equals(dataType)) {
            // Text类型不比较长度
            if (columnType.contains(DataBaseConstant.DATE_) || columnType.contains(DataBaseConstant.BLOB_) || columnType.contains(DataBaseConstant.TEXT_)) {
                return columnName.equals(meta.getColumnName()) && isNullable.equals(meta.isNullable);
            } else {
                return columnType.equals(meta.getColumnType()) && isNullable.equals(meta.isNullable) && columnSize == meta.getColumnSize();
            }
        } else {
            if (columnType.contains(DataBaseConstant.DATE_) || columnType.contains(DataBaseConstant.BLOB_) || columnType.contains(DataBaseConstant.TEXT_)) {
                return columnType.equals(meta.getColumnType()) && columnName.equals(meta.getColumnName())
                        && isNullable.equals(meta.isNullable)
                        && isEquals(columnComment, meta.getColumnComment()) && isEquals(columnDefaultValue, meta.getColumnDefaultValue());
            } else {
                return columnType.equals(meta.getColumnType())
                        && isNullable.equals(meta.isNullable) && columnSize == meta.getColumnSize()
                        && isEquals(columnComment, meta.getColumnComment()) && isEquals(columnDefaultValue, meta.getColumnDefaultValue());
            }
        }
    }

    /**
     * 比较数据库表列备注
     *
     * @param meta - 数据库表
     * @return boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/9/30 9:31
     */
    public boolean equalsDefault(ColumnMeta meta) {
        if (meta == this) {
            return true;
        }
        return isEquals(columnComment, meta.getColumnComment());
    }

    /**
     * 比较数据库表列备注
     *
     * @param meta - 数据库表
     * @return boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/9/30 9:31
     */
    public boolean equalsComment(ColumnMeta meta) {
        if (meta == this) {
            return true;
        }
        return isEquals(columnComment, meta.getColumnComment());
    }

    /**
     * 比较字符串
     *
     * @param newString - 字符串
     * @param oldString - 字符串
     * @return boolean - 比较结果
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/9/30 9:22
     */
    private boolean isEquals(String newString, String oldString) {
        boolean aBooleanNew = ConvertUtils.isNotEmpty(newString);
        boolean aBooleanOld = ConvertUtils.isNotEmpty(oldString);
        if (aBooleanNew != aBooleanOld) {
            return false;
        }
        if (aBooleanNew) {
            return newString.equals(oldString);
        }
        return true;
    }

    @Override
    public int hashCode() {
        return columnSize + columnType.hashCode() * columnName.hashCode();
    }

    @Override
    public String toString() {
        return columnName + "," + columnType + "," + isNullable + "," + columnSize;
    }

}